/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.sgsmcan.Controlador;

import com.sgsmcan.Dao.AmoDao;
import com.sgsmcan.Dao.AmoDaoImpl;
import com.sgsmcan.Dao.ColorDao;
import com.sgsmcan.Dao.ColorDaoImpl;
import com.sgsmcan.Dao.PerroDao;
import com.sgsmcan.Dao.PerroDaoImpl;
import com.sgsmcan.Dao.RazaDao;
import com.sgsmcan.Dao.RazaDaoImpl;
import com.sgsmcan.Entidad.Amo;
import com.sgsmcan.Entidad.Color;
import com.sgsmcan.Entidad.Perro;
import com.sgsmcan.Entidad.Raza;
import com.sgsmcan.EntidadFiltro.PerroFiltro;
import com.sgsmcan.Exporter.Exporter;
import com.sgsmcan.Utils.DataExporter;
import com.sgsmcan.Utils.FiltroHibernate;
import com.sgsmcan.Utils.Paginacion;
import com.sgsmcan.Utils.Utilitario;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.faces.application.NavigationHandler;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import org.hibernate.criterion.DetachedCriteria;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.UploadedFile;

/**
 *
 * @author Luis Ballena
 */
@ManagedBean(name = "perroBean")
@ViewScoped
public class PerroControlador implements Serializable {

    /*Daos*/
    private PerroDao daoPerro;
    private RazaDao daoRaza;
    private AmoDao daoAmo;
    private ColorDao daoColor;
    /*Entidades*/
    private LazyDataModel<Perro> perros;
    private LazyDataModel<Amo> amos;
    private List<Raza> razas;
    private Map contenedorColores;
    private List<Color> colores;
    private Color color;
    private Raza raza;
    private Amo amo;
    private Perro perro;
    private UploadedFile file;
    /*Entidad Filtro*/
    private PerroFiltro perroFiltro;
    /*Auxiliar*/
    Date fecha;
    Date fechaActual = new Date();
    Integer flagDueño;
    boolean activatePanel = true;
    boolean activateColor;
    /*Para los permisos*/
    @ManagedProperty("#{usuarioBean}")
    private UsuarioControlador usuarioSesion;

    public PerroControlador() {
        raza = new Raza();
        amo = new Amo();
        daoPerro = new PerroDaoImpl();
        daoRaza = new RazaDaoImpl();
        daoAmo = new AmoDaoImpl();
        daoColor = new ColorDaoImpl();
        perroFiltro = new PerroFiltro();
        perro = new Perro();
    }

    public void initLista() {
        if (!FacesContext.getCurrentInstance().isPostback()) {
            usuarioSesion.generarModulo(3);
            perros = new Paginacion<Perro>(daoPerro.getPerros());
            razas = daoRaza.getRazas();
        }
    }

    public void initUpdate() {
        if (!FacesContext.getCurrentInstance().isPostback()) {
            Object parametro = Utilitario.getFlash("idPerro");
            if (parametro == null) {
                FacesContext fc = FacesContext.getCurrentInstance();
                NavigationHandler nh = fc.getApplication().getNavigationHandler();
                nh.handleNavigation(fc, null, "/views/perros/list.xhtml?faces-redirect=true");
                return;
            }
            Integer id = (Integer) parametro;
            amos = new Paginacion<Amo>(daoAmo.getAmos());
            razas = daoRaza.getRazas();
            perro = daoPerro.getPerro(id);
            raza = perro.getRaza();
            if (perro.getAmo() != null) {
                flagDueño = Integer.parseInt(Utilitario.RESOURCE_BUNDLE.getString("prop_dueño"));
                amo = perro.getAmo();
            }
            color = perro.getColor();
            cargarMapaColores();
            definirColor();
            fecha = new Date(perro.getFechaNacimiento().getTime());
        }
    }

    public void initInsertar() {
        if (!FacesContext.getCurrentInstance().isPostback()) {
            razas = daoRaza.getRazas();
            amos = new Paginacion<Amo>(daoAmo.getAmos());
            perro = new Perro();
            color = new Color();
            cargarMapaColores();
            colores = new ArrayList<Color>();
        }
    }

    private void cargarMapaColores() {
        contenedorColores = new HashMap();
        List<Color> colors = daoColor.getColores();
        for (Color colore : colors) {
            contenedorColores.put(colore.getId(), colore);
        }
    }

    public void insertarPerro(ActionEvent event) {
        perro.setFoto("si.jpg");
        if (!esValido()) {
            return;
        }
        perro.setFechaNacimiento(new java.sql.Date(fecha.getTime()));
        perro.setRaza(raza);
        perro.setColor(color);
        try {
            if (flagDueño == Integer.parseInt(Utilitario.RESOURCE_BUNDLE.getString("prop_dueño"))) {
                perro.setAmo(amo);
            }
            daoPerro.insertar(perro);
        } catch (Exception e) {
            Utilitario.LOG.error("Error en PerroControlador", e);
            return;
        }
        limpiar();
        Utilitario.enviarMensajeGlobalValido("Se ha guardado correctamente");
    }

    public void actualizarPerro(ActionEvent event) {

        if (!esValido()) {
            return;
        }
        perro.setFechaNacimiento(new java.sql.Date(fecha.getTime()));
        perro.setRaza(raza);
        perro.setColor(color);
        try {
            if (flagDueño == Integer.parseInt(Utilitario.RESOURCE_BUNDLE.getString("prop_dueño"))) {
                daoAmo.actualizar(amo);
                perro.setAmo(amo);
            } else {
                perro.setAmo(null);
                flagDueño = Integer.parseInt(Utilitario.RESOURCE_BUNDLE.getString("prop_muni"));
            }
            daoPerro.actualizar(perro);
            /*Para cargar los nuevos datos tomados por el trigger*/
            perro = daoPerro.getPerro(perro.getId());
            amo = perro.getAmo();
        } catch (Exception e) {
            Utilitario.LOG.error("Error en PerroControlador", e);
            return;
        }
        Utilitario.enviarMensajeGlobalValido("Se ha actualizado correctamente");
    }

    public void subirFoto(FileUploadEvent event) {
        perro = daoPerro.getPerro(perro.getId());
        setFile(event.getFile());
        if (getFile() == null) {
            Utilitario.enviarMensajeGlobalError("Se debe seleccionar una imagen jpg/gif/png");
            return;
        }
        try {
            perro.setFoto(perro.getId() + "-" + perro.getNombre() + ".jpg");
            Utilitario.TransferFile(perro.getFoto(), getFile().getInputstream(), Utilitario.RESOURCE_BUNDLE.getString("path_imagen_perro") + "\\");
        } catch (Exception ex) {
            Utilitario.enviarMensajeGlobalError("Ha ocurrido un error al leer la imagen");
            Utilitario.LOG.error("Error en subirFoto", ex);
            ex.printStackTrace();
            return;
        }
        try {
            daoPerro.actualizar(perro);
        } catch (Exception e) {
            Utilitario.enviarMensajeGlobalError("Ha ocurrido un error al guardar la imagen");
            e.printStackTrace();
            return;
        }
        Utilitario.enviarMensajeGlobalValido("Se ha actualizado correctamente");
    }

    public String irActualizar(Integer id) {
        Utilitario.putFlash("idPerro", id);
        return "updatePerro";
    }

    public void buscarFiltro(ActionEvent evnt) {
        FiltroHibernate filtro = new FiltroHibernate(daoPerro.getPerros());
        filtro.addLikeNullParametro(perroFiltro.getNombre(), "perro.nombre");
        filtro.addComboParametro(perroFiltro.getIdRaza(),"rza.id");
        filtro.addRangeFecha(perroFiltro.getDateMin(), perroFiltro.getDateMax(),"perro.fechaNacimiento");
        DetachedCriteria criteria = filtro.executeFiltro();
        perros = new Paginacion<Perro>(criteria);
    } 
    
    public void limpiarFiltro(ActionEvent evnt) {
        perros = new Paginacion<Perro>(daoPerro.getPerros());
        perroFiltro = new PerroFiltro();
    }

    public void capturar(Integer id) {
        amo = (Amo) daoAmo.getAmo(id);
    }

    public void prepararEliminar(int id) {
        perro.setId(id);
    }

    public void eliminarPerro(ActionEvent evnt) {
        perro = daoPerro.getPerro(perro.getId());
        perro.setEstado(Boolean.FALSE);
        daoPerro.eliminar(perro);
        Utilitario.enviarMensajeGlobalValido("Se ha eliminado correctamente");
    }

    public void definirColor() {
        colores = new ArrayList<Color>();
        switch (raza.getId()) {
            /*Perros que solo tienen un color*/
            case 3:
                color.setId(1);
            case 5:
                color.setId(9);
            case 6:
                color.setId(8);
            case 7:
                color.setId(5);
                setActivateColor(false);
                break;
            case 1:
                setActivateColor(true);
                colores.add((Color) contenedorColores.get(3));
                colores.add((Color) contenedorColores.get(4));
                colores.add((Color) contenedorColores.get(6));
                break;
            case 2:
                setActivateColor(true);
                colores.add((Color) contenedorColores.get(2));
                colores.add((Color) contenedorColores.get(4));
                break;
            case 4:
                setActivateColor(true);
                colores.add((Color) contenedorColores.get(1));
                colores.add((Color) contenedorColores.get(3));
                break;
        }
    }

    private boolean esValido() {
        if (!esNombreValido()) {
            return false;
        }
        if (fecha == null) {
            Utilitario.enviarMensajeGlobalError("Debe ingresar la fecha de Nacimiento");
            return false;
        }
        if (flagDueño == Integer.parseInt(Utilitario.RESOURCE_BUNDLE.getString("prop_dueño"))) {
            if (amo.getId() == null) {
                Utilitario.enviarMensajeGlobalError("Debe seleccionar un donante");
            }
        }
        return true;
    }

    private boolean esNombreValido() {
        if (Utilitario.esNulo(perro.getNombre())) {
            Utilitario.enviarMensajeGlobalError("Debe ingresar el nombre del Perro");
            return false;
        } else if (!Utilitario.esSoloLetras(perro.getNombre())) {
            Utilitario.enviarMensajeGlobalError("El nombre del perro debe ser solo letras");
            return false;
        } else if (!Utilitario.esRangoValido(perro.getNombre(), 50)) {
            Utilitario.enviarMensajeGlobalError("El maximo de caracteres del nombre es 50");
            return false;
        }
        return true;
    }

    private void limpiar() {
        perro = new Perro();
        raza = new Raza();
        amo = new Amo();
        flagDueño = 0;
    }

    public void exportar(ActionEvent event) {
        Paginacion<Perro> paginacion = (Paginacion<Perro>) perros;
        List<Perro> lista = paginacion.getAllList();
        if (lista.isEmpty()) {
            return;
        }
        Exporter exporter = lista.get(0);
        DataExporter<Perro> dataExporter = new DataExporter<Perro>(exporter);
        dataExporter.crearDocumento(lista);
        FacesContext facesContext = FacesContext.getCurrentInstance();
        ExternalContext externalContext = facesContext.getExternalContext();
        externalContext = DataExporter.getResponseContent(externalContext,"perros");
        try {
            OutputStream outputStream = externalContext.getResponseOutputStream();
            dataExporter.exportarDocumento(outputStream);
            externalContext.setResponseStatus(200);
            externalContext.responseFlushBuffer();
            facesContext.responseComplete();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /*  GETTER AND SETTER   */
    public Perro getPerro() {
        return perro;
    }

    public void setPerro(Perro perro) {
        this.perro = perro;
    }

    public Raza getRaza() {
        return raza;
    }

    public void setRaza(Raza raza) {
        this.raza = raza;
    }

    public List<Raza> getRazas() {
        return razas;
    }

    public void setRazas(List<Raza> razas) {
        this.razas = razas;
    }

    public LazyDataModel<Perro> getPerros() {
        return perros;
    }

    public void setPerros(LazyDataModel<Perro> perros) {
        this.perros = perros;
    }

    public PerroFiltro getPerroFiltro() {
        return perroFiltro;
    }

    public void setPerroFiltro(PerroFiltro perroFiltro) {
        this.perroFiltro = perroFiltro;
    }

    public Date getFecha() {
        return fecha;
    }

    public void setFecha(Date fecha) {
        this.fecha = fecha;
    }

    public UploadedFile getFile() {
        return file;
    }

    public void setFile(UploadedFile file) {
        this.file = file;
    }

    public Integer getFlagDueño() {
        return flagDueño;
    }

    public void setFlagDueño(Integer flagDueño) {
        this.flagDueño = flagDueño;
    }

    public Amo getAmo() {
        return amo;
    }

    public void setAmo(Amo amo) {
        this.amo = amo;
    }

    public LazyDataModel<Amo> getAmos() {
        return amos;
    }

    public void setAmos(LazyDataModel<Amo> amos) {
        this.amos = amos;
    }

    public Date getFechaActual() {
        return fechaActual;
    }

    public void setFechaActual(Date fechaActual) {
        this.fechaActual = fechaActual;
    }

    public boolean isActivateColor() {
        return activateColor;
    }

    public void setActivateColor(boolean activateColor) {
        this.activateColor = activateColor;
    }

    public List<Color> getColores() {
        return colores;
    }

    public void setColores(List<Color> colores) {
        this.colores = colores;
    }

    public Color getColor() {
        return color;
    }

    public void setColor(Color color) {
        this.color = color;
    }

    public boolean isActivatePanel() {
        return activatePanel;
    }

    public void setActivatePanel(boolean activatePanel) {
        this.activatePanel = activatePanel;
    }

    public void setUsuarioSesion(UsuarioControlador usuarioSesion) {
        this.usuarioSesion = usuarioSesion;
    }
}
